package com.ruoyi.attendance.service.impl;

import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Set;
import java.util.stream.Collectors;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.attendance.dto.ScheduleQueryDTO;
import com.ruoyi.attendance.entity.ScheduleManagement;
import com.ruoyi.attendance.mapper.ScheduleManagementMapper;
import com.ruoyi.attendance.service.ScheduleService;
import com.ruoyi.attendance.vo.ScheduleRecordVO;
import com.ruoyi.attendance.vo.ScheduleUserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;

@Slf4j
@Service
public class ScheduleServiceImpl implements ScheduleService {

    @Autowired
    private ScheduleManagementMapper scheduleManagementMapper;

    // 日期格式，与ScheduleRecordVO的String类型匹配
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    // 日期格式，与数据库存储格式一致
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public List<ScheduleUserVO> listScheduleUsers(ScheduleQueryDTO query) {
        // 自动补全时间范围（如果为空）
        // handleDateRange(query);

            // 获取当前时间
            Date currentDate = new Date();

            if (query.getStartDate() == null && query.getEndDate() == null) {
                // query.setStartDate(currentDate); // 设置为当前日期
                // 测试, 设置开始时间是当前的前30天
                query.setStartDate(new Date(currentDate.getTime() - 7L * 24 * 60 * 60 * 1000));
                // 设置结束日期为当前日期的未来30天
                query.setEndDate(new Date(currentDate.getTime() + 30L * 24 * 60 * 60 * 1000) );
            }else if (query.getStartDate() == null) {
                // 设置为结束日期的前30天
                query.setStartDate(new Date(query.getEndDate().getTime() - 30L * 24 * 60 * 60 * 1000));
            } else if (query.getEndDate() == null) {
                // 设置为开始日期的未来30天
                query.setEndDate(new Date(query.getStartDate().getTime() + 30L * 24 * 60 * 60 * 1000));
            }

        // 1. 查询用户列表
        List<ScheduleUserVO> userList = scheduleManagementMapper.selectUserList(query);
            // log.info("userList:" + userList.toString());

        // 2. 为每个用户查询排班记录
        for (ScheduleUserVO user : userList) {
            List<ScheduleRecordVO> schedules = scheduleManagementMapper.selectScheduleListByUserId(
                    user.getUserId(),
                    query.getStartDate(),
                    query.getEndDate()
            );
            user.setScheduleList(schedules);
        }
        // log.info("userList:" + userList.toString());
        return userList;
    }

    @Override
    @Transactional
    public Map<String, Object> generateDefaultSchedules(Integer days) {
        // 处理默认天数
        if (days == null || days <= 0) {
            days = 100;
        }

        // 计算日期范围（今天到未来days天） - 使用java.util.Date
        Calendar calendar = Calendar.getInstance();
        Date startDate = calendar.getTime(); // 今天

        calendar.add(Calendar.DAY_OF_YEAR, days);
        Date endDate = calendar.getTime(); // 未来days天

        // 查询所有有效用户
        ScheduleQueryDTO query = new ScheduleQueryDTO();
        query.setPageNum(1);
        query.setPageSize(Integer.MAX_VALUE); // 获取所有用户
        List<ScheduleUserVO> userList = scheduleManagementMapper.selectUserList(query);

        int totalUsers = userList.size();
        int totalDays = days;
        int totalRecordsGenerated = 0;

        // 为每个用户生成排班计划
        for (ScheduleUserVO user : userList) {
            // 查询用户已有排班记录
            List<ScheduleRecordVO> existingSchedules = scheduleManagementMapper.selectScheduleListByUserId(
                    user.getUserId(),
                    startDate,  // 直接使用Date类型
                    endDate     // 直接使用Date类型
            );

            // 已有排班记录的日期集合（修改部分）
            Set<String> existingDates = existingSchedules.stream()
                    .map(ScheduleRecordVO::getScheduleDate)  // 直接获取String类型日期
                    .collect(Collectors.toSet());

            // 生成需要插入的排班记录（使用Entity类）
            List<ScheduleManagement> recordsToInsert = new ArrayList<>();
            calendar.setTime(startDate);

            while (!calendar.getTime().after(endDate)) {
                // Date currentDate = calendar.getTime();

                Date currentDate = calendar.getTime();

                // 将Date转换为String（格式：yyyy-MM-dd）
                LocalDate localDate = currentDate.toInstant()
                        .atZone(ZoneId.systemDefault())
                        .toLocalDate();
                String currentDateStr = localDate.format(formatter);

                if (existingDates.contains(currentDateStr)) {
                    calendar.add(Calendar.DAY_OF_YEAR, 1);
                    continue;
                }

                int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
                boolean isWeekend = (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY);

                // 创建默认排班记录（使用Entity类）
                ScheduleManagement record = new ScheduleManagement();
                record.setUserId(user.getUserId());
                record.setUserPosition(user.getPosition());
                record.setScheduleDate(currentDate); // 直接使用Date类型
                record.setAttendancePoliciesId((int) (isWeekend ? 0L : 1L));
                record.setDelFlag(0);

                recordsToInsert.add(record);
                calendar.add(Calendar.DAY_OF_YEAR, 1);
            }

            // 获取今天的日期（格式：yyyy-MM-dd）
            LocalDate todayLocalDate = LocalDate.now();
            String todayStr = todayLocalDate.format(formatter);

            // 过滤掉当天的记录（重点优化：只检查一次）
            recordsToInsert.removeIf(record -> {
                LocalDate recordDate = record.getScheduleDate().toInstant()
                        .atZone(ZoneId.systemDefault())
                        .toLocalDate();
                return recordDate.isEqual(todayLocalDate);
            });

            if (!recordsToInsert.isEmpty()) {
                scheduleManagementMapper.batchInsertSchedules(recordsToInsert);
                totalRecordsGenerated += recordsToInsert.size();
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "排班计划生成成功");
        result.put("totalUsers", totalUsers);
        result.put("totalDays", totalDays);
        result.put("totalRecordsGenerated", totalRecordsGenerated);
        return result;
    }

    @Override
    public int updateScheduleManagement(ScheduleManagement scheduleManagement) {
        return scheduleManagementMapper.updateScheduleManagement(scheduleManagement);
    }

    @Override
    public ScheduleManagement getScheduleManagementByIdAndDate(Integer id, Date date) {
        log.info("id:{}, date:{}", id, date);
        return scheduleManagementMapper.getScheduleManagementByIdAndDate(id, date);
    }

    @Override
    public List<ScheduleManagement> getScheduleManagementByIdAndDateList(Integer id, Date date) {
        log.info("ScheduleManagementServiceImpl.getScheduleManagementByIdAndDateList()");
        log.info("id:{}, date:{}", id, date);
        return scheduleManagementMapper.getScheduleManagementByIdAndDateList(id, date);
    }

    // 新增：将LocalDate转换为String类型日期
    private String convertToString(LocalDate localDate) {
        if (localDate == null) {
            return null;
        }
        return localDate.format(DATE_FORMATTER);
    }

    // 新增：将String类型日期转换为LocalDate
    private LocalDate convertToLocalDate(String dateStr) {
        if (dateStr == null || dateStr.isEmpty()) {
            return null;
        }
        return LocalDate.parse(dateStr, DATE_FORMATTER);
    }


}
